﻿Imports Orekaria.Lib.P2P
Imports System.Threading

Public Class P2PWrapper
    Implements IDisposable
    Private Shared _p2PHelper As P2PHelper
    Private ReadOnly _th As Thread
    Private _disposing As Boolean = False
    Private ReadOnly _hostList As List(Of HostHelper)
    Private ReadOnly _hostPropio As HostHelper
    Private _elTurnoLoTiene As HostHelper = Nothing

    Public Sub New()
        _p2PHelper = New P2PHelper(My.Settings.Puerto, False)
        _hostPropio = New HostHelper(LocalhostIP, Environment.UserName)
        _hostList = New List(Of HostHelper)
        _hostList.Add(HostPropio)
        _th = New Thread(AddressOf GestionP2P)
        _th.Start()
    End Sub

    Private Sub GestionP2P()
        While (Not _disposing)
            For i = 0 To 10
                Thread.Sleep(100)
                While _p2PHelper.Received.Count > 0
                    ProcesaPaquete(_p2PHelper.Received.Dequeue)
                End While
            Next
        End While
    End Sub

    Private Sub ProcesaPaquete(s As String)
        Debug.Print(s)
        Dim partes = s.Split(" ")
        ' hasta el primer espacio es el nombre del host que envía el mensaje

        ' nombre host que envía
        ' catalógalo si no lo está ya
        Dim hostOrigen = CatalogaHost(partes(0))

        If partes.Length = 2 Then
            hostOrigen.PingReceived(Convert.ToInt32(partes(1)))
            Return
        End If

        ' hasta el segundo espacio es el nombre del host al que se le envía el mensaje
        Dim destino = partes(1)
        Dim hostDestino = CatalogaHost(destino)

        Dim mb = New MensajeBroadcasted(s, Convert.ToInt32(partes(2)), partes(3))
        ' Guarda de quién es el turno
        If mb.Tipo = TipoMensaje.Disparo Then
            _elTurnoLoTiene = hostDestino
        End If
        hostDestino.MessageReceived(mb)
    End Sub

    Private Function CatalogaHost(ByVal hostName As String) As HostHelper
        Dim ip = Convert.ToByte(hostName.Substring(0, 3))
        hostName = hostName.Substring(3)
        Dim hostEncontrado = _hostList.FirstOrDefault(Function(h)
                                                          Return h.HostIp = ip
                                                      End Function)
        If hostEncontrado Is Nothing Then
            hostEncontrado = New HostHelper(ip, hostName)
            _hostList.Add(hostEncontrado)
        End If
        Return hostEncontrado
    End Function

    Public ReadOnly Property EsMiTurno As Boolean
        Get
            If ElTurnoLoTiene Is Nothing Then Return False
            Return ElTurnoLoTiene = _hostPropio
        End Get
    End Property

    Public ReadOnly Property HostList As List(Of HostHelper)
        Get
            Return _hostList
        End Get
    End Property

    Public ReadOnly Property HostPropio As HostHelper
        Get
            Return _hostPropio
        End Get
    End Property

    Public ReadOnly Property ElTurnoLoTiene As HostHelper
        Get
            Return _elTurnoLoTiene
        End Get
    End Property

    Public Sub Dispose() Implements IDisposable.Dispose
        _disposing = True
        _th.Join()
        _p2PHelper.Dispose()
    End Sub

    Public Sub Send(mensaje As String)
        _p2PHelper.Send(String.Format("{0} {1}", _hostPropio.IDHost, mensaje))
    End Sub

    Public Sub SendCediendoTurno(ByVal mensaje As String)
        _elTurnoLoTiene = Nothing
        Send(mensaje)
    End Sub

    Public Sub EstablecePrimerTurno()
        If Not ElTurnoLoTiene Is Nothing Then
            Throw New ArgumentException("Solo puedes llamar a esta función una vez y ha de ser al principio de la partida")
        End If
        Dim i = -1
        For Each h As HostHelper In _hostList
            If h.BoletoLoteriaTurno > i Then
                i = h.BoletoLoteriaTurno
                _elTurnoLoTiene = h
            End If
        Next
    End Sub
End Class

